<template>
    <div class="page-wrap" v-loading="loading">
        <!-- 搜索表单 -->
        <el-card class="search-form-card">
            <div class="search-form-wrap">
                <div class="search-form-item">
                    <div class="search-form-item-label">名称：</div>
                    <div class="search-form-item-input">
                        <el-input v-model="search_form.name" placeholder="请输入" :size="size" @keyup.native.enter="handleFormSearch"></el-input>
                    </div>
                </div>
                <div class="search-form-item">
                    <div class="search-form-item-label">路径：</div>
                    <div class="search-form-item-input">
                        <el-input v-model="search_form.path" placeholder="请输入" :size="size" @keyup.native.enter="handleFormSearch"></el-input>
                    </div>
                </div>
                <div class="search-form-item">
                    <div class="search-form-item-label"></div>
                    <div class="search-form-item-input">
                        <el-button type="primary" :size="size" icon="el-icon-search"
                            @click="handleFormSearch">查询</el-button>
                        <el-button :size="size" @click="handleSearchFormReset">重置</el-button>
                    </div>
                </div>
            </div>
        </el-card>

        <!-- 表格区域 -->
        <el-card class="table-card">
            <!-- 工具栏 -->
            <div class="toolbar-box">
                <div class="left-box">
                    <el-button :size="size" icon="el-icon-refresh" @click="handleRefreshList"></el-button>
                    <el-button :size="size" icon="el-icon-plus" type="success" v-if="showAddBtn"
                        @click="handleAddRow">新增</el-button>
                    <el-button :size="size" icon="el-icon-edit" type="success" @click="handleEditRow" v-if="showEditBtn"
                        :disabled="selectedRows.length != 1">编辑</el-button>
                    <el-button :size="size" icon="el-icon-delete" type="danger" @click="handleDelRows('')" v-if="showDelBtn" :disabled="selectedRows.length == 0">删除</el-button>
                </div>
                <div class="right-box">
                    <!-- <el-button :size="size" icon="el-icon-download">导出</el-button> -->
                </div>
            </div>
            <!-- 表格内容 -->
            <div class="table-box">
                <el-table :data="showTableData" style="width: 100%" :border="border" :size="size"  row-key="id"  ref="table"
                :tree-props="{children: 'children'}" :cell-class-name="cellClassName" :expand-row-keys="expandRowKeys"
                    @selection-change="handleSelectionChange" @expand-change="expandChange">
                    <el-table-column type="selection" width="50" align="center">
                    </el-table-column>
                    <el-table-column prop="title" label="标题">
                    </el-table-column>
                    <el-table-column prop="name" label="名称">
                    </el-table-column>
                    <el-table-column prop="path" label="路径">
                    </el-table-column>
                    <el-table-column prop="icon" label="图标">
                    </el-table-column>
                    <el-table-column prop="remarks" label="备注">
                    </el-table-column>
                    <el-table-column prop="sort" label="排序" width="100" align="center">
                    </el-table-column>
                    <el-table-column prop="isMenu" label="菜单" width="100" align="center">
                        <template slot-scope="scope">
                            <el-switch v-model="scope.row.isMenu" :active-value="1" :inactive-value="0"
                                @change="handleUpdateField(scope.row, 'isMenu')"></el-switch>
                        </template>
                    </el-table-column>
                    <el-table-column prop="operate" label="操作" width="100" align="center">
                        <template slot-scope="scope">
                            <el-button type="success" icon="el-icon-edit" circle size="mini" @click="handleEditRow(scope.row)" v-if="showEditBtn"></el-button>
                            <el-button type="danger" icon="el-icon-delete" circle size="mini" @click="handleDelRows(scope.row.id)" v-if="showDelBtn"></el-button>
                        </template>
                    </el-table-column>
                </el-table>
            </div>
        </el-card>

        <!-- 分页 -->
        <!-- <div class="pagination-wrap">
            <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange"
                :current-page="currentPage" :page-sizes="pageSizes" :page-size="pageSize" :pager-count="pagerCount"
                layout="total, sizes, prev, pager, next" :total="total">
            </el-pagination>
        </div> -->

        <!-- 弹窗 -->
        <form-dialog ref="formDialog" :title="dialog_title" @submit="handleSubmit"></form-dialog>
    </div>
</template>

<script>
//引入混入逻辑
import mixin from '@/mixins/table'
//引入接口配置
import {indexApi, addApi, editApi, delApi, updateFieldApi} from '@/api/permission'
//引入弹出组件
import formDialog from './components/form-dialog.vue'
import {mapState, mapGetters, mapMutations, mapActions} from 'vuex'

// 关于导入导出
// 1.菜单导入功能仅用于系统初始化阶段
// 2.当前系统中已有菜单数据，无法再次导入
// 3.如需新增菜单，请使用“新增”按钮进行操作

export default {
    name: 'permission',
    //CRUD所定义的字段和方法在mixin定义
    mixins: [mixin],
    data() {
        return {
            indexApi, addApi, editApi, delApi, updateFieldApi,//接口注册
            
            search_form: {
                name: "",
                path: "",
            },//搜索表单

            filter_form: {
                name: "",
                path: "",
            },//筛选表单
            expandRowKeys: [],//要展开的行

            loading: false,//页面加载状态
        }
    },
    components: {
        formDialog
    },
    created() {
        //获取表格数据(使用全局数据代替)
        //this.getTableData()
    },
    methods: {
        ...mapActions(['menuInit']),
        //处理表单提交事件
        handleSubmit(form){
            //处理pid字段
            if(form.pid === ""){
                form.pid = 0
            }           
            //执行提交请求
            this.requestSubmit(form)
        },
        //自定义单元格样式
        cellClassName({row, column, rowIndex, columnIndex}){
            //名称
            if(column.property == 'name' && this.filter_form.name && row.name.includes(this.filter_form.name)){
                return 'match-text'
            }
            //路径
            if(column.property == 'path' && this.filter_form.path && row.path.includes(this.filter_form.path)){
                return 'match-text'
            }
            return ""
        },
        //表格展开事件
        expandChange(row, expanded){
            //展开
            if(expanded){
                //从列表中删除
                this.expandRowKeys.push(row.id + '')
            }else{
                //收起
                var index = this.expandRowKeys.findIndex(item=>{
                    return item == row.id
                })
                //从列表中删除
                this.expandRowKeys.splice(index, 1)
            }
        },
        //重写 获取表格数据
        async getTableData() {
            try {
                //开启加载状态
                this.loading = true
                //请求菜单数据（全局）
                await this.menuInit(this)
                //关闭加载状态
                this.loading = false
            } catch (error) {
                console.log('error', error)
                //关闭加载状态
                this.loading = false
            }
        },
        //重写 删除多行
        async handleDelRows(id){
            try {
                //参数准备（有传id表示单个删除，否则表示多选删除）
                //动态标题
                if(id){
                    var ids = [id]
                    var title = "确定删除此项?"
                }else{
                    //多选删除
                    var ids = this.selectedRows.map(row=>{
                        return row.id
                    })
                    var title = `确定删除选中的 ${ids.length} 项?`
                }

                //判断要删除的菜单是否有子菜单
                //遍历要删除的菜单
                const hasSubMenu = ids.some(delId=>{
                    //遍历全部菜单
                    for(var key in this.menuOrigin){
                        var menu = this.menuOrigin[key]
                        //要删除的菜单是否是其他菜单的父级菜单
                        if(menu.pid == delId){
                            //存在子菜单
                            return true
                        }
                    }
                    //全部遍历完成，没有发现子菜单
                    return false
                })
                //有子菜单，不允许删除
                if(hasSubMenu){
                    this.$message.warning('要删除的菜单中存在子菜单，请先删除子菜单后再试！')
                    return
                }
                //提示
                if(hasSubMenu){
                    title = "要删除的菜单中存在子菜单，是否确认删除?"
                }
                //确认框
                await this.$confirm(title, '提示', {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    type: 'warning'
                })
                //处理删除事件
                this.handleDelete(ids)
            } catch (error) {
                console.log('error', error)
            }
        },
        //重写 查询逻辑
        handleFormSearch(){
            //更新记录查询数据
            this.filter_form = this.$utils.deepCopy(this.search_form)
            this.$nextTick((function(){
                //收起已展开的展开的行
                this.retractRows()
                //展开菜单
                if(this.filter_form.name.trim() !== "" || this.filter_form.path.trim() !== ""){
                    //满足条件的原始菜单
                    const filerList = this.menuOriginHasChildren.filter(item=>{
                        return item.name.trim().includes(this.filter_form.name) && item.path.trim().includes(this.filter_form.path)
                    })
                    //递归调用，将父级菜单展开
                    filerList.forEach(item=>{
                        //如果存在父级菜单，则将父级菜单添加进来，且接着递归遍历是否还有上上一级
                        const parent = this.menuOrigin.find(_item=>{
                            return item.pid == _item.id
                        })
                        if(parent){
                            //添加时转换为字符串
                            this.expandRowKeys.push(parent.id + '')
                            //递归遍历
                            this.expandParents(parent)
                        }
                    })
                }
            }))
        },
        //重写 重置逻辑
        handleSearchFormReset(){
            //重置记录查询数据
            this.search_form = {
                name: "",
                path: "",
            }
            this.filter_form = {
                name: "",
                path: "",
            }
            //数据变动，导致showTableData重新渲染
            this.$nextTick(function(){
                //收起已展开的展开的行
                this.retractRows()
            })
        },
        //收起已展开的展开的行
        retractRows(){
            const rows = this.expandRowKeys.map(id=>{
                //根据id找到row
                return this.menuOrigin.find(item=>{
                    return item.id == id
                })
            })
            rows.forEach((row)=>{
                this.$refs['table'].toggleRowExpansion(row,false)
            })
            this.expandRowKeys = []
        },
        //添加父级菜单
        addParents(item, filerList = []){
            //如果存在父级菜单，则将父级菜单添加进来，且接着递归遍历是否还有上上一级
            const parent = this.menuOrigin.find(_item=>{
                return item.pid == _item.id
            })
            if(parent){
                //将父级菜单添加列表(添加前去重)
                const index = filerList.findIndex(_item=>{
                    return _item.id == parent.id
                })
                if(index == -1){
                    filerList.push(parent)
                }
                //递归遍历
                this.addParents(parent, filerList)
            }
        },
        //添加子菜单
        addChildren(children = [], filerList = []){
            children.forEach(item=>{
                //将子菜单添加到列表（防重复）
                const index = filerList.findIndex(_item=>{
                    return _item.id == item.id
                })
                if(index == -1){
                    filerList.push(item)
                }

                //递归添加子菜单
                if(item.children){
                    this.addChildren(item.children, filerList)
                }
            })
        },
        //展开父级菜单
        expandParents(item){
            //如果存在父级菜单，则将父级菜单添加进来，且接着递归遍历是否还有上上一级
            const parent = this.menuOrigin.find(_item=>{
                return item.pid == _item.id
            })
            if(parent){
                //添加时转换为字符串
                this.expandRowKeys.push(parent.id + '')
                //递归遍历
                this.expandParents(parent)
            }
        },
    },
    computed: {
        ...mapState(['menuOrigin','menuOriginHasChildren']),
        //要展示的表格数据
        showTableData(){
            //空的搜索
            if(this.filter_form.name.trim() === "" && this.filter_form.path.trim() === ""){
                //深拷贝一份
                var menuList = this.$utils.deepCopy(this.menuOrigin)
            }else{
                //满足条件的原始菜单
                const filerList = this.menuOriginHasChildren.filter(item=>{
                    return item.name.trim().includes(this.filter_form.name) && item.path.trim().includes(this.filter_form.path)
                })
                //这些菜单的父级菜单也要添加进来(递归调用),子菜单也要添加进来
                filerList.forEach(item=>{
                    //如果存在父级菜单，则将父级菜单添加进来，且接着递归遍历是否还有上上一级
                    const parent = this.menuOrigin.find(_item=>{
                        return item.pid == _item.id
                    })
                    if(parent){
                        //将父级菜单添加列表(添加前去重)
                        const index = filerList.findIndex(_item=>{
                            return _item.id == parent.id
                        })
                        if(index == -1){
                            filerList.push(parent)
                        }
                        //递归遍历
                        this.addParents(parent, filerList)
                    }
                    //添加子菜单
                    if(item.children){
                        this.addChildren(item.children, filerList)
                    }
                })
                //深拷贝一份，移除所有children属性
                var menuList = filerList.map(item=>{
                    const _item = {
                        ...item
                    }
                    delete _item.children
                    return _item
                })
            }

            //转换成树形对象
            const menuTree = this.$utils.buildTree(menuList)
            //将树形对象最外层转换成数组
            const menuTreeArr = []
            for(var key in menuTree){
                menuTreeArr.push(menuTree[key])
            }
            //深度排序
            this.$utils.deepSort(menuTreeArr)
            return menuTreeArr
        },
    }
}
</script>

<style scoped lang="scss">
.page-wrap{
    ::v-deep .match-text{
        color: #E6A23C !important;
    }
}
</style>